package controller;

import cache.ListConfigCache;
import com.alibaba.fastjson.JSON;
import listboxlib.constant.ListBoxConstant;
import listboxlib.pageutils.Order;
import listboxlib.pageutils.PageBounds;
import listboxlib.pageutils.PageList;
import model.dto.ListConfigDTO;
import model.dto.ListInfoDTO;
import model.dto.ListQueryDTO;
import model.dto.PageListDTO;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import service.ListBoxImpl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Auther: arcadia
 * @Date: 18-11-24 09 58
 * @Description: 列表工具控制器
 */
@Controller
@RequestMapping("/list")
public class ListBoxController {

    @Autowired
    ListBoxImpl listBoxImpl;

    /**
     * 页数
     */
    private int page = 1;

    /**
     * 单页条数
     */
    private int limit = 10;

    /**
     * 排序
     */
    private String orderType = "desc";

    private ThreadLocal<Map<String, String>> fieldNameMapLocal = new ThreadLocal<>();

    @RequestMapping("/query")
    @ResponseBody
    public void queryList(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ListQueryDTO listQueryDTO = new ListQueryDTO();
        String funcId = request.getParameter("funcId");
        if (!StringUtils.isEmpty(request.getParameter("page"))) {
            page = Integer.parseInt(request.getParameter("page"));
        }

        if (!StringUtils.isEmpty(request.getParameter("limit"))) {
            limit = Integer.parseInt(request.getParameter("limit"));
        }
        String orderBy = request.getParameter("orderBy");
        if (!StringUtils.isEmpty(request.getParameter("orderType"))) {
            orderType = request.getParameter("orderType");
        }
        PageBounds pageBounds = null;
        if (!StringUtils.isEmpty(orderBy)) {
            if (ListBoxConstant.Direction.DESC.type.equals(orderType)) {
                Order order = new Order(orderBy, Order.Direction.DESC, ListBoxConstant.Direction.DESC.type);
                pageBounds = new PageBounds(page, limit, order);
            } else if (ListBoxConstant.Direction.ASC.type.equals(orderType)) {
                Order order = new Order(orderBy, Order.Direction.ASC, ListBoxConstant.Direction.ASC.type);
                pageBounds = new PageBounds(page, limit, order);
            }
        } else {
            pageBounds = new PageBounds(page, limit);
        }
        Map<String, String> fieldNameMap = ListConfigCache.getFieldNameMap(funcId);
        fieldNameMapLocal.set(fieldNameMap);
        List<ListConfigDTO> listConfig = ListConfigCache.getListConfig(funcId);
        ListInfoDTO listInfo = ListConfigCache.getListInfo(funcId);
        Map<String, String[]> parameterMap = request.getParameterMap();
        String statement = listInfo.getNameSpace() + "." + listInfo.getFuncId();
        listQueryDTO.setStatement(statement);
        listQueryDTO.setConfigDTOS(listConfig);
        listQueryDTO.setCreatorClass(listInfo.getPlaceHolder());
        listConfig.forEach(listConfigDTO -> {
            String fieldName = listConfigDTO.getFieldName();
            String[] values = parameterMap.get(fieldName);
            if (!StringUtils.isEmpty(values)) {
                if (ListBoxConstant.Field_Find_Model.Range.key.equals(listConfigDTO.getFindType())) {
                    Arrays.sort(values, (s1, s2) -> {
                        DateTime dateTime1 = new DateTime(s1, DateTimeZone.forID("+08:00"));
                        DateTime dateTime2 = new DateTime(s2, DateTimeZone.forID("+08:00"));
                        return dateTime1.compareTo(dateTime2);
                    });
                }
                listConfigDTO.setFieldValue(values);
            }
        });
        List<PageList<Object>> dataList = listBoxImpl.getDateList(listQueryDTO, pageBounds);
        // 检查不一定准 这里如果去掉ArrayList转化 ，检查就会报转化异常
        List<Map<String, String>> pageList  = convertToFieldValue((ArrayList) dataList);
        PageListDTO pageListDTO = new PageListDTO(((PageList) dataList).getPaginator(), pageList);
        PrintWriter writer = response.getWriter();
        writer.print(JSON.toJSONString(pageListDTO));
    }


    /**
     * 后台列表字段名映射前台展示字段名
     */
    @SuppressWarnings(value = "unchecked")
    private List<Map<String, String>> convertToFieldValue(ArrayList dataList) {
        //为什么这里Collectors解析不出来我的实际List类型，返回一个Object
        return (List<Map<String,String>>)(dataList).stream().map(data -> {
            Set<Map.Entry<String, String>> entries = ((Map<String, String>) data).entrySet();
            return entries.stream().collect(Collectors.toMap(castKey().compose(Map.Entry::getKey), Map.Entry::getValue));
        }).collect(Collectors.toList());
    }


    private Function<String, String> castKey() {
        return this::tranKeyToField;
    }

    private String tranKeyToField(String key) {
        Map<String, String> fieldNameMap = fieldNameMapLocal.get();
        return fieldNameMap.get(key);
    }

}
